﻿#include "cmainframe.h"
#include "custombitmapbutton.h"
#include "nodemanager/wnodemanager.h"
#include "nodemanager/crouteconditions.h"
#include "gui/guimanager.h"
#include "resources/icon.xpm"

#if defined (WIN32)
#include "CrashRpt.h"
#endif

#include "serversettingsdialog.h"
#include "parampreviewdlg.h"
#include "luaanalyzer.h"
#include "ziputility.h"
#include "locomanager/locomanager.h"

#include <wx/aboutdlg.h>
#include <wx/fileconf.h>

initialiseSingleton(CMainFrame);

wxDEFINE_EVENT(DIR_CHANGED_EVENT, wxThreadEvent);

BEGIN_EVENT_TABLE( CMainFrame, wxFrame )
    EVT_BUTTON(IDD_BUTTON_SAVEALL,CMainFrame::handlerBtnSaveAll)
    EVT_AUINOTEBOOK_PAGE_CLOSE(IDD_NOTEBOOKPROCONTENT, CMainFrame::handlerNoteBookClose)
    //EVT_KEY_DOWN(CMainFrame::OnKeyDown)
    EVT_AUI_RENDER(CMainFrame::OnAuiManagerPaneUpdated)
    EVT_CLOSE(CMainFrame::OnClose)
END_EVENT_TABLE()

CMainFrame::CMainFrame(const wxString& title,
                       const wxPoint& pos,
                       const wxSize& size)
    : wxFrame(nullptr, wxID_ANY, title,pos,size),
      m_WorkingMode(WorkingMode::MODE_EIDTING)
{
    SetIcon(wxIcon(icon_xpm));

    // 1. 创建菜单栏
    wxMenuBar *menuBar = new wxMenuBar();

    // 2. 创建文件菜单
    wxMenu *fileMenu = new wxMenu();
    fileMenu->AppendSeparator();
    wxMenuItem* exitItem = new wxMenuItem(fileMenu, IDD_MENU_EXIT, wxT("退出\tCtrl+Q"), wxT("退出应用程序"));
    exitItem->SetBitmap(wxArtProvider::GetBitmap(wxART_QUIT, wxART_MENU));
    fileMenu->Append(exitItem);

    // 3. 创建设置菜单
    wxMenu *setMenu = new wxMenu();
    wxMenuItem* serversetItem = new wxMenuItem(setMenu,IDD_MENU_SERVERSET, wxT("服务器设置"), wxT("设置服务器参数"));
    serversetItem->SetBitmap(wxArtProvider::GetBitmap(wxART_TIP, wxART_MENU));
    setMenu->Append(serversetItem);

    m_editMenu = new wxMenu();
    wxMenuItem* createnewprojectItem = new wxMenuItem(m_editMenu, IDD_MENU_CREATNEWPROJECT, wxT("建立新项目"), wxT("建立新项目."));
    createnewprojectItem->SetBitmap(wxArtProvider::GetBitmap(wxART_NEW, wxART_MENU));
    wxMenuItem* stationsetItem = new wxMenuItem(m_editMenu, IDD_MENU_STATIONPARAMSET, wxT("站场参数设置向导"), wxT("用于设置站场参数并实时预览."));
    stationsetItem->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_MENU));
    wxMenuItem* loadprojectItem = new wxMenuItem(m_editMenu, IDD_MENU_LOADPROJECT, wxT("导入项目"), wxT("导入项目."));
    loadprojectItem->SetBitmap(wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_MENU));
    wxMenuItem* saveprojectItem = new wxMenuItem(m_editMenu, IDD_MENU_SAVEPROJECT, wxT("保存项目"), wxT("保存项目."));
    saveprojectItem->SetBitmap(wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_MENU));
    m_editMenu->Append(createnewprojectItem);
    m_editMenu->Append(stationsetItem);
    m_editMenu->Append(loadprojectItem);
    m_editMenu->Append(saveprojectItem);

    // 4. 创建帮助菜单
    wxMenu *helpMenu = new wxMenu();
    wxMenuItem* helpItem = new wxMenuItem(setMenu,IDD_MENU_ABOAT, wxT("关于"), wxT("关于.."));
    helpItem->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP, wxART_MENU));
    helpMenu->Append(helpItem);

    // 5. 将菜单添加到菜单栏
    menuBar->Append(fileMenu, wxT("&文件"));
    menuBar->Append(setMenu, wxT("&设置"));
    menuBar->Append(m_editMenu, wxT("&编辑"));
    menuBar->Append(helpMenu, wxT("&帮助"));

    // 6. 设置菜单栏到框架
    SetMenuBar(menuBar);

    // 统一绑定到同一个处理函数
    Bind(wxEVT_MENU,
         &CMainFrame::OnMainFrameMenu,
         this,
         IDD_MENU_STATIONPARAMSET,IDD_MENU_CREATNEWPROJECT);

    Bind(DIR_CHANGED_EVENT, &CMainFrame::OnDirChangedEvent, this);

    // 绑定按键按下事件
    Bind(wxEVT_CHAR_HOOK, &CMainFrame::OnKeyDown, this);

    // 设置应用标题
    this->SetTitle(wxString::Format("%s - %s",wxT(IDD_APPLICTION_NAME),wxT(IDD_APPLICTION_VERSION)));

    // 创建状态栏
    m_systemStatusBar = CreateStatusBar();
    m_systemStatusBar->SetFieldsCount(1);

 #if defined (WIN32)
    wxString crashreportpath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+"\\CrashReports";

    CR_INSTALL_INFO info;
    memset(&info, 0, sizeof(CR_INSTALL_INFO));
    info.cb = sizeof(CR_INSTALL_INFO);             // Size of the structure
    info.pszAppName = _T(IDD_APPLICTION_NAME); // App name
    info.pszAppVersion = _T(IDD_APPLICTION_VERSION);              // App version
    //info.pszEmailSubject = _T("股道自动化管理系统故障报告"); // Email subject
    //info.pszEmailTo = _T("test@hotmail.com");      // Email recipient address
    info.pszErrorReportSaveDir = crashreportpath.ToStdWstring().c_str(); // 崩溃报告保存目录
    info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS;
    info.dwFlags |= CR_INST_DONT_SEND_REPORT;
    //把Dump压缩成zip文件
    info.dwFlags |= CR_INST_STORE_ZIP_ARCHIVES;
    info.dwFlags |= CR_INST_AUTO_THREAD_HANDLERS;
    info.uMiniDumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory);
                                                   // Install crash handlers
    int nInstResult = crInstall(&info);

    // Check result
    if (nInstResult != 0)
    {
        TCHAR buff[256];
        crGetLastErrorMsg(buff, 256); // Get last error
        LOGE(buff);
    }
#endif

    // 结点管理系统
    new CRouteConditions();
    new WNodeManager();
    new GuiManager();
    new LuaAnalyzer();
    new LocoManager();

    // 创建 AUI 管理器
    m_auimgr.SetManagedWindow(this);
    m_auimgr.SetFlags(wxAUI_MGR_DEFAULT);

    m_maindrawscene = new maindrawscene(this);

    wxPanel *psystemlogtextPanel = new wxPanel(this);
    //psystemlogtextPanel->SetMinSize(wxSize(300,30));
    wxBoxSizer* systemlogtextPanelsizer = new wxBoxSizer(wxHORIZONTAL);
    m_systemlogtextCtrl = new wxRichTextCtrl(psystemlogtextPanel, wxID_ANY,
                                        wxT(""),
                                        wxDefaultPosition, wxDefaultSize,
                                        wxTE_MULTILINE|wxTE_READONLY);
    systemlogtextPanelsizer->Add(m_systemlogtextCtrl,  1, wxEXPAND | wxALL, 0);
    psystemlogtextPanel->SetSizer(systemlogtextPanelsizer);

    wxPanel *pscirptAuiNotebooksPanel = new wxPanel(this);
    //pscirptAuiNotebooksPanel->SetMinSize(wxSize(300,300));
    wxBoxSizer* scirptAuiNotebookssizer = new wxBoxSizer(wxHORIZONTAL);
    m_scirptAuiNotebooks = new wxAuiNotebook(pscirptAuiNotebooksPanel,IDD_NOTEBOOKPROCONTENT,
        wxDefaultPosition,wxDefaultSize,wxAUI_NB_DEFAULT_STYLE|wxAUI_NB_TOP|wxNO_BORDER);
    scirptAuiNotebookssizer->Add(m_scirptAuiNotebooks,  1, wxEXPAND | wxALL, 0);
    pscirptAuiNotebooksPanel->SetSizer(scirptAuiNotebookssizer);

    m_auimgr.AddPane(m_maindrawscene, wxAuiPaneInfo().
                 Name(wxT("主绘制面板")).Caption(wxT("主绘制面板")).
                 CenterPane());
    m_auimgr.AddPane(pscirptAuiNotebooksPanel, wxAuiPaneInfo()
                 .Name(wxT("脚本编辑面板"))
                 .Caption(wxT("脚本编辑"))
                 .CaptionVisible(false)  // 隐藏标题栏
                 .Right()
                 .Layer(1)
                 .MinSize(500, 500));
    m_auimgr.AddPane(psystemlogtextPanel, wxAuiPaneInfo()
                 .Name(wxT("系统日志输出"))
                 .Caption(wxT("系统日志输出"))
                 .Bottom()
                 .Layer(0)
                 .MinSize(600, 120)
                 .CloseButton(true));

    // 初始化日志系统
    new ScriptManager();
    ScriptManager::getSingleton().lua_init();

    // 初始化日志系统
    ILog4zManager::getInstance()->start();

    new WTcpClient(this);

    // 主日志器配置
    ILog4zManager::getInstance()->setLoggerPath(LOG4Z_MAIN_LOGGER_ID, "./logs");
    ILog4zManager::getInstance()->setLoggerOutFile(LOG4Z_MAIN_LOGGER_ID, true);
    //ILog4zManager::getInstance()->setLoggerFileMaxSize(LOG4Z_MAIN_LOGGER_ID, 50 * 1024 * 1024); // 50MB
    ILog4zManager::getInstance()->setLoggerLevel(LOG4Z_MAIN_LOGGER_ID, LOG_LEVEL_DEBUG);

    // 导入语法分析参数
    wxString tmpGrammarNoteFilePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+wxT("/resources/configs/grammarnotes.json");
    if(LuaAnalyzer::getSingleton().loadGrammarNotes(tmpGrammarNoteFilePath.ToStdString()))
    {
        LOGI(wxT("语法分析参数加载成功."));
    }

    // 获取当前程序脚本的完整路径
    m_curScriptWorkingPath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+wxT("/resources/scripts");

    m_fileWatcher.addWatch( m_curScriptWorkingPath.ToStdString(), this, true );
    LOGI(wxString(wxT("监控目录:")+m_curScriptWorkingPath).ToUTF8().data());

    m_fileWatcher.watch();

    // 注册类到lua
    ScriptManager::getSingleton().registertoLua();

    // 导入脚本并执行
    ScriptManager::getSingleton().exe_lua_string_for_path(m_curScriptWorkingPath);

    // 加载系统初始脚本
    loadInitSystemScript();

    m_scirptAuiNotebooks->Update();

    // 更新 AUI 管理器
    m_auimgr.Update();

    m_lastPopupTime = wxDateTime::Now().Subtract(wxTimeSpan::Hours(24));
    m_authorizationchecktimer = new wxTimer(this, wxID_ANY);
    this->Bind(wxEVT_TIMER,
               &CMainFrame::OnAuthorizationCheckTimer,
               this,
               m_authorizationchecktimer->GetId());
    m_authorizationchecktimer->Start(20000);
    m_sysInitTimer = new wxTimer(this, wxID_ANY);
    m_scriptLoadTimer = new wxTimer(this,wxID_ANY);
    this->Bind(wxEVT_TIMER,
               &CMainFrame::OnSystemInitTimer,
               this,
               m_sysInitTimer->GetId());
    this->Bind(wxEVT_TIMER,
               &CMainFrame::OnScriptLoadTimer,
               this,
               m_scriptLoadTimer->GetId());
    m_sysInitTimer->StartOnce(1000);

    this->printlog(LOG_LEVEL_INFO,"系统启动成功.");

    // 信号服务器和结点管理器绑定在一起
    WTcpClient::getSingleton().setNetworkFrameManager(WNodeManager::getSingletonPtr());

    // 启动http服务器
    m_HttpServer.setNetworkFrameManager(this);
    m_HttpServer.setWorkingPath(wxT("/home/ou/interlocker4/bin/test"));
    m_HttpServer.Open(wxT("127.0.0.1"),8080);

    // 启动websocket服务器
    m_WebSocketServer.setNetworkFrameManager(this);
    m_WebSocketServer.setServerParams(wxT("127.0.0.1"),8081);
    m_WebSocketServer.Open();

    // 程序启动后，切换到工作模式
    this->changeWorkingMode();

    this->Maximize();
    this->CenterOnScreen();
}

CMainFrame::~CMainFrame()
{
    m_auimgr.UnInit();

#if defined (WIN32)
    crUninstall();
#endif

    delete WNodeManager::getSingletonPtr();
    delete CRouteConditions::getSingletonPtr();
    delete GuiManager::getSingletonPtr();
    delete WTcpClient::getSingletonPtr();
    delete LuaAnalyzer::getSingletonPtr();
    delete LocoManager::getSingletonPtr();
    delete m_maindrawscene;
    m_maindrawscene = NULL;
    delete m_systemlogtextCtrl;
    m_systemlogtextCtrl = NULL;
    delete m_scirptAuiNotebooks;
    m_scirptAuiNotebooks = NULL;
    delete m_authorizationchecktimer;
    m_authorizationchecktimer = NULL;
    delete m_sysInitTimer;
    m_sysInitTimer = NULL;
    delete m_scriptLoadTimer;
    m_scriptLoadTimer = NULL;

    ScriptManager::getSingleton().lua_exit();
    delete ScriptManager::getSingletonPtr();
}

void CMainFrame::OnMainFrameMenu(wxCommandEvent& event)
{
    switch(event.GetId())
    {
    case IDD_MENU_SAVEPROJECT:                  // 菜单 - 保存项目
    {
        wxString zipFile = wxFileSelector(wxT("保存项目文件"), wxT(""), wxT(""), wxT("lok"),
                                          wxT("项目文件 (*.lok)|*.lok"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
        if (zipFile.empty()) return;

        if (!zipFile.EndsWith(wxT(".lok"))) {
            zipFile += wxT(".lok");
        }

        wxString dirToZip = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+wxT("\\resources\\scripts");

        if (ZipUtility::ZipDirectory(dirToZip, zipFile)) {
            wxMessageBox(wxT("项目文件保存成功!"), wxT("完成"), wxOK | wxICON_INFORMATION);
        } else {
            wxMessageBox(wxT("项目文件保存失败: ") + ZipUtility::GetLastError(), wxT("错误"), wxOK | wxICON_ERROR);
        }
    }
        break;
    case IDD_MENU_LOADPROJECT:                  // 菜单 - 导入项目
    {
        wxString zipFile = wxFileSelector(wxT("导入项目文件"), wxT(""), wxT(""), wxT("lok"),
                                          wxT("项目文件 (*.lok)|*.lok"), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
        if (zipFile.empty()) return;

        wxString targetDir = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+wxT("\\resources\\scripts");

        if (ZipUtility::UnzipFile(zipFile, targetDir)) {
            wxMessageBox(wxT("项目文件导入成功!"), wxT("完成"), wxOK | wxICON_INFORMATION);
        } else {
            wxMessageBox(wxT("项目文件导入失败: ") + ZipUtility::GetLastError(), wxT("错误"), wxOK | wxICON_ERROR);
        }
    }
        break;
    case IDD_MENU_STATIONPARAMSET:              // 菜单 - 站场参数设置
    {
        ParamPreviewDlg pParamPreviewDlg(this,wxT("站场参数设置向导"));
        if(pParamPreviewDlg.ShowModal() == wxID_PREVIEW)
        {

        }
    }
        break;
    case IDD_MENU_SERVERSET:              // 菜单 - 服务器设置
    {
        wxFileConfig config(wxT(IDD_APPLICTION_NAME));
        int serverport = 0;
        wxString serverip = config.Read(wxT("signalserverip"));
        config.Read("signalserverport",&serverport);

        // 创建并显示对话框
        ServerSettingsDialog dlg(this,
                                 wxT("服务器设置"));
        dlg.SetSignalServerParams(serverip.empty() ? wxT("127.0.0.1") : serverip,
                                  serverport <= 0 ? 8888 : serverport);

        if (dlg.ShowModal() == wxID_OK)
        {
            config.Write("signalserverip",dlg.GetSignalServerIP());
            config.Write("signalserverport",dlg.GetSignalServerPort());

            if(WTcpClient::getSingleton().connect(dlg.GetSignalServerIP(),
                                                 dlg.GetSignalServerPort()))
            {
                this->printlog(LOG_LEVEL_INFO,
                               wxString::Format(wxT("信号服务器启动成功,侦听 %s:%d"),
                                dlg.GetSignalServerIP(),
                                dlg.GetSignalServerPort()).ToUTF8().data());
            }
        }
    }
        break;
    case IDD_MENU_ABOAT:                        // 帮助 - 关于选项
    {
        wxAboutDialogInfo aboutInfo;
        aboutInfo.SetName(wxT(IDD_APPLICTION_NAME));
        aboutInfo.SetVersion(wxT(IDD_APPLICTION_VERSION));
        aboutInfo.SetDescription(wxT(IDD_APPLICTION_DESCRIPTION));
        aboutInfo.SetCopyright(wxT("(C) 2025 成都市红枫科技有限公司"));
        aboutInfo.AddDeveloper(wxT("akinggw@126.com"));
        aboutInfo.SetWebSite(wxT("https://gitee.com/akinggw"), wxT("红枫软件"));
        aboutInfo.SetIcon(wxIcon(icon_xpm));

        wxAboutBox(aboutInfo, this);
    }
        break;
    case IDD_MENU_EXIT:
    {
        this->Close();
    }
        break;
    case IDD_MENU_CREATNEWPROJECT:
    {
        // 弹出确认对话框
        wxMessageDialog dialog(
            this,
            wxT("建立新的项目，将清空以前的数据，是否已经备份数据，是否继续?"),
            wxT("确认"),
            wxYES_NO | wxICON_QUESTION | wxICON_WARNING
            );

        if (dialog.ShowModal() == wxID_YES) {
            wxString configfilepath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + wxT("/resources/scripts/站场配置.lua");

            wxFile decfile;
            if (decfile.Create(configfilepath, true))
            {
                wxCSConv conv("UTF-8");

                if (!decfile.Write(wxT("stationConfig = [[]];"),conv)) {

                }

                decfile.Close();
            }
        }
    }
        break;
    default:
        break;
    }
}

void CMainFrame::OnScriptLoadTimer(wxTimerEvent& event)
{
    event.Skip();
}

void CMainFrame::OnAuiManagerPaneUpdated(wxAuiManagerEvent& event)
{
    event.Skip();
}

void CMainFrame::OnSystemInitTimer(wxTimerEvent& event)
{
    // 设置应用标题
    this->SetTitle(wxString::Format(wxT("%s - %s [%s]"),
                                    wxT(IDD_APPLICTION_NAME),
                                    wxT(IDD_APPLICTION_VERSION),
                                    (m_License.isAuthorization() ? wxT("正式版") : wxT("编辑版"))));
}

void CMainFrame::OnAuthorizationCheckTimer(wxTimerEvent& event)
{
    wxDateTime now = wxDateTime::Now();

    // 检查是否在20:00之后（晚上8点后）
    if (!m_License.isAuthorization() &&
        now.GetHour() >= 20)
    {
        // 计算距离上次弹窗的时间差
        //wxTimeSpan timeSinceLastPopup = now - m_lastPopupTime;

        // 如果超过1分钟或从未弹过窗
        //if (timeSinceLastPopup.GetMinutes() >= 1 || !m_lastPopupTime.IsValid())
        //{
            wxMessageBox(m_License.getTipString(),
                         wxT("提醒"),
                         wxOK | wxICON_INFORMATION,
                         this);
        //    m_lastPopupTime = now; // 更新最后弹窗时间
        //}
    }
}

/// 切换工作模式
void CMainFrame::changeWorkingMode(void)
{
    m_WorkingMode = (m_WorkingMode == WorkingMode::MODE_WORKING ? WorkingMode::MODE_EIDTING : WorkingMode::MODE_WORKING);

    switch(m_WorkingMode)
    {
    case WorkingMode::MODE_WORKING:
    {
        m_auimgr.GetPane(wxT("系统日志输出")).Show(false);
        m_auimgr.GetPane(wxT("脚本编辑面板")).Show(false);
        m_auimgr.Update();

        m_editMenu->Enable(IDD_MENU_STATIONPARAMSET,false);
        m_editMenu->Enable(IDD_MENU_CREATNEWPROJECT,false);
        m_editMenu->Enable(IDD_MENU_LOADPROJECT,false);
        m_editMenu->Enable(IDD_MENU_SAVEPROJECT,false);

        //this->printlog(LOG_LEVEL_INFO,"系统已经切换为[工作模式]");
        m_systemStatusBar->SetStatusText(wxT("系统已经切换为[工作模式]"));
    }
        break;
    case WorkingMode::MODE_EIDTING:
    {
        m_auimgr.GetPane(wxT("系统日志输出")).Show(true);
        m_auimgr.GetPane(wxT("脚本编辑面板")).Show(true);
        m_auimgr.Update();

        m_editMenu->Enable(IDD_MENU_STATIONPARAMSET,true);
        m_editMenu->Enable(IDD_MENU_CREATNEWPROJECT,true);
        m_editMenu->Enable(IDD_MENU_LOADPROJECT,true);
        m_editMenu->Enable(IDD_MENU_SAVEPROJECT,true);

        //this->printlog(LOG_LEVEL_INFO,"系统已经切换为[编辑模式]");
        m_systemStatusBar->SetStatusText(wxT("系统已经切换为[编辑模式]"));
    }
        break;
    default:
        break;
    }

    WNodeManager::getSingleton().setWorkingMode(m_WorkingMode);
}

/// 保存所有的文件
void CMainFrame::saveAllFiles(void)
{
    if(m_scirptAuiNotebooks == NULL) return;

    for(int i=0;i<m_scirptAuiNotebooks->GetPageCount();i++)
    {
        if(m_scirptAuiNotebooks->GetPageText(i).Find("*") < 0)
            continue;

        MainScriptEditor *pMainScriptEditor = static_cast<MainScriptEditor*>(m_scirptAuiNotebooks->GetPage(i));
        if(pMainScriptEditor)
            pMainScriptEditor->SaveFile();
    }

    wxString tmpStr = wxT("所有文件保存成功,脚本重新加载并运行.");
    wxString formatted1 = wxDateTime::Now().Format("[%Y-%m-%d %H:%M:%S] ");
    m_systemStatusBar->SetStatusText(formatted1+tmpStr);

    printlog(LOG_LEVEL_INFO,tmpStr.ToUTF8().data());
}

void CMainFrame::OnClose(wxCloseEvent& event)
{
    // 弹出确认对话框
    wxMessageDialog dialog(
        this,
        wxT("您是否要退出系统?"),
        wxT("退出确认"),
        wxYES_NO | wxICON_QUESTION | wxICON_WARNING
    );

    if (dialog.ShowModal() == wxID_YES) {
        // 先保存所有的文件
        this->saveAllFiles();

        event.Skip();
    } else {
        event.Veto();
    }
}

void CMainFrame::handlerBtnSaveAll(wxCommandEvent& event)
{
    saveAllFiles();
}

/// 加载指定结点的脚本文件
void CMainFrame::loadNodeScriptFile(wxString nodepath)
{
    for(int i=0;i<m_scirptAuiNotebooks->GetPageCount();i++)
    {
        if(m_scirptAuiNotebooks->GetPageText(i).Find(nodepath) >= 0)
            return;
    }

    wxString pmaindrawscenescriptfile = wxString::Format(wxT("%s/nodes/%s"),
                                                         m_curScriptWorkingPath,
                                                         nodepath);

    if(m_scirptAuiNotebooks == NULL ||
       !wxFileName::FileExists(pmaindrawscenescriptfile))
        return;

    MainScriptEditor *pMainScriptEditor = new MainScriptEditor(this);
    pMainScriptEditor->LoadFile(pmaindrawscenescriptfile);
    pMainScriptEditor->setAuiNotebook(m_scirptAuiNotebooks);
    pMainScriptEditor->setCurrentOperatorFile(pmaindrawscenescriptfile);

    m_scirptAuiNotebooks->AddPage(pMainScriptEditor,
                                  wxString::Format("%s",nodepath),
                                  true,
                                  wxArtProvider::GetBitmapBundle(wxART_HELP_PAGE, wxART_OTHER).GetBitmap(wxSize(16, 16)));
    m_scirptAuiNotebooks->Update();
}

/// 加载指定的脚本文件
void CMainFrame::loadScriptFile(wxString filepath,const wxArtID& artid)
{
    for(int i=0;i<m_scirptAuiNotebooks->GetPageCount();i++)
    {
        if(m_scirptAuiNotebooks->GetPageText(i).Find(filepath) >= 0)
            return;
    }

    wxString pmaindrawscenescriptfile = wxString::Format(wxT("%s/%s"),
                                                         m_curScriptWorkingPath,
                                                         filepath);

    if(m_scirptAuiNotebooks == NULL ||
       !wxFileName::FileExists(pmaindrawscenescriptfile))
        return;

    MainScriptEditor *pMainScriptEditor = new MainScriptEditor(this);
    pMainScriptEditor->LoadFile(pmaindrawscenescriptfile);
    pMainScriptEditor->setAuiNotebook(m_scirptAuiNotebooks);
    pMainScriptEditor->setCurrentOperatorFile(pmaindrawscenescriptfile);

    m_scirptAuiNotebooks->AddPage(pMainScriptEditor,
                                  filepath,
                                  true,
                                  wxArtProvider::GetBitmapBundle(artid, wxART_OTHER).GetBitmap(wxSize(16, 16)));
    m_scirptAuiNotebooks->Update();
}

/// 加载系统初始脚本
void CMainFrame::loadInitSystemScript(void)
{
    wxString pmaindrawscenescriptfile = wxString::Format("%s/%s",
                                                         m_curScriptWorkingPath,
                                                         wxT(IDD_INIT_SYSTEM_SCRIPT_FILE));

    //printlog(LOG_LEVEL_INFO,pmaindrawscenescriptfile);

    if(m_scirptAuiNotebooks == NULL ||
       !wxFileName::FileExists(pmaindrawscenescriptfile))
        return;

    MainScriptEditor *pMainScriptEditor = new MainScriptEditor(this);
    pMainScriptEditor->LoadFile(pmaindrawscenescriptfile);
    pMainScriptEditor->setAuiNotebook(m_scirptAuiNotebooks);
    pMainScriptEditor->setCurrentOperatorFile(pmaindrawscenescriptfile);

    m_scirptAuiNotebooks->AddPage(pMainScriptEditor,
                                  wxT(IDD_INIT_SYSTEM_SCRIPT_FILE),
                                  true,
                                  wxArtProvider::GetBitmapBundle(wxART_GO_HOME, wxART_OTHER).GetBitmap(wxSize(16, 16)));
    //m_scirptAuiNotebooks->SetPageCloseButton(m_scirptAuiNotebooks->GetPageIndex(pMainScriptEditor), false);
    m_scirptAuiNotebooks->Update();
}

/// 在状态栏上打印文本
void CMainFrame::printStatusBar(wxString msg)
{
    if(m_systemStatusBar == NULL || msg == "")
        return;

    m_systemStatusBar->SetStatusText(msg);
}

/// 打印日志
void CMainFrame::printlog(int level,std::string str,bool issave)
{
    if(str == "" || m_systemlogtextCtrl == NULL) return;

    //std::lock_guard<std::mutex> lock(m_MainFrameMutex);

    wxString decStr = wxString::FromUTF8(str);

    if(m_systemlogtextCtrl->GetNumberOfLines() > 2000)
        m_systemlogtextCtrl->Clear();

    wxRichTextAttr colText;
    colText.SetTextColour(*wxWHITE);

    switch(level)
    {
    case LOG_LEVEL_ERROR:
    {
        colText.SetTextColour(*wxRED);
    }
        break;
    case LOG_LEVEL_WARN:
    {
        colText.SetTextColour(*wxLIGHT_GREY);
    }
        break;
    case 7:
    {
        colText.SetTextColour(*wxGREEN);
    }
        break;
    case 8:
    {
        colText.SetTextColour(*wxBLUE);
    }
        break;
    case 9:
    {
        colText.SetTextColour(*wxCYAN);
    }
        break;
    default:
        break;
    }

    wxString formatted1 = wxDateTime::Now().Format("[%Y-%m-%d %H:%M:%S] ");

    // 使用 WriteText 而不是 AppendText
    m_systemlogtextCtrl->MoveEnd();
    m_systemlogtextCtrl->BeginStyle(colText);
    m_systemlogtextCtrl->WriteText(formatted1 + decStr + "\n");
    m_systemlogtextCtrl->EndStyle();

    // 强制刷新
    m_systemlogtextCtrl->Refresh();

    // 获取最后一行位置
    long lastPos = m_systemlogtextCtrl->GetLastPosition();

    // 滚动到末尾（确保可见）
    m_systemlogtextCtrl->ScrollIntoView(lastPos, WXK_END);
    m_systemlogtextCtrl->ShowPosition(lastPos);

    if(issave)
        LOG_STREAM(LOG4Z_MAIN_LOGGER_ID,level,str);
}

void CMainFrame::OnKeyDown(wxKeyEvent& event)
{
    int keyCode = event.GetKeyCode();

    switch(keyCode) {
        case WXK_F5:
            this->saveAllFiles();
            break;
        case WXK_F9:   // 模式切换
            this->changeWorkingMode();
            break;
        default:
            break;
    }

    event.Skip();
}

void CMainFrame::handlerNoteBookClose(wxAuiNotebookEvent& event)
{
    /*MainScriptEditor* pMainScriptEditor = static_cast<MainScriptEditor*>(m_scirptAuiNotebooks->GetPage(event.GetSelection()));
    if(pMainScriptEditor &&
       pMainScriptEditor->getCurrentOperatorFile().Find(IDD_INIT_SYSTEM_SCRIPT_FILE) > 0)
    {
        wxMessageBox(IDD_INIT_SYSTEM_SCRIPT_FILE+wxString("不能关闭!"),"警告");
        event.Veto();
    }*/

    event.Skip();
}

void CMainFrame::OnScriptChangedEvent(efsw::Action action,wxString dir,wxString fileName,wxString oldFilename)
{
    if(action == efsw::Action::Modified)
    {
        wxString pdecScriptFile = dir + fileName;
        if(!wxFileExists(pdecScriptFile))
            pdecScriptFile = dir + oldFilename;

        if(!wxFileExists(pdecScriptFile))
            return;

        wxString decFileMd5 = getFileContentMd5(pdecScriptFile);

        // 防止脚本文件重复加载
        if(decFileMd5 != "" && m_inputFileMd5[pdecScriptFile] == decFileMd5)
        {
            //CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,
            //                                    wxString::Format(wxT("%s没有改变,不重复导入."),pdecScriptFile).ToUTF8());
            return;
        }

        bool isRestartSys = false;

        if(pdecScriptFile.Find(wxT(IDD_INIT_SYSTEM_SCRIPT_FILE)) > 0 ||
            pdecScriptFile.Find(wxT(IDD_STATION_CONFIG_SCRIPT_FILE)) > 0)
            isRestartSys = true;

        if(isRestartSys)
        {
            // 重置脚本系统
            ScriptManager::getSingleton().CreateIsolatedLuaEnvironment();

            // 重置所有结点
            WNodeManager::getSingleton().resetAllNodes();
        }

        // 导入脚本并执行
        ScriptManager::getSingleton().exe_lua_string_for_file(pdecScriptFile);

        if(isRestartSys)
        {
            // 调用lua初始函数
            ScriptManager::getSingleton().callLuaFunctionWithSystemInit();
        }

        m_inputFileMd5[pdecScriptFile] = decFileMd5;
    }
}

/// 打开信号服务器
void CMainFrame::openSignalServer(void)
{
    wxFileConfig config(wxT(IDD_APPLICTION_NAME));
    int serverport = 0;
    wxString serverip = config.Read("signalserverip");
    config.Read("signalserverport",&serverport);

    if(serverip != "" && serverport > 0)
    {
        WTcpClient::getSingleton().connect(serverip,serverport);
    }
}

void CMainFrame::OnDirChangedEvent(wxThreadEvent& event)
{
    wxArrayString pParams = SplitString(event.GetString(),"$");
    if(pParams.size() != 4)
        return;

    wxString tmpPath = pParams[0].Mid(0,pParams[0].length()-1);

    if(tmpPath.Contains(m_curScriptWorkingPath))
    {
        // 处理脚本目录变化
        OnScriptChangedEvent((efsw::Action)wxAtoi(pParams[3]),
                             pParams[0],
                             pParams[1],
                             pParams[2]);
    }
}

void CMainFrame::handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, std::string oldFilename)
{
    wxString pParams = wxString(dir)+
            "$"+
            wxString(filename.c_str(), wxConvUTF8)+
            "$"+
            wxString(oldFilename.c_str(), wxConvUTF8)+
            "$"+
            wxString::Format("%d",action);

    wxThreadEvent event(DIR_CHANGED_EVENT);
    event.SetString(pParams);

    wxQueueEvent(wxApp::GetMainTopWindow(), event.Clone());
}

/// 处理网络字符串消息
void CMainFrame::OnWebSocketProcessNetText(WebSocketlientInfo* client,wxString mes)
{
    m_WebSocketServer.SendMessageAll(wxString::Format(wxT("返回消息:%s"),mes));
}

/// 处理http消息
bool CMainFrame::OnProcessHttpMessage(const WHttpRequest& request, WHttpResponse& response)
{
    wxString method = request.GetMethod();
    wxString path = request.GetPath();
    std::map<wxString, wxString> params = request.GetAllParams();

    if(path == wxT("/testparam"))
    {
        wxString decString = wxString::Format("%s %s:",method,path);

        std::map<wxString, wxString>::iterator iter = params.begin();
        for(;iter != params.end();++iter)
        {
            decString += wxString::Format("%s:%s",(*iter).first,(*iter).second);
        }

        response.SetContent(decString);

        return true;
    }

    return false;
}
